
# Compiler toolchain
CC = gcc
AS = gas
LD = ld
OBJCOPY = objcopy
OBJDUMP = objdump

# Compiler and linker flags
LDFLAGS = -m elf_i386 -nostdlib 
CFLAGS = -pipe -Wall -Werror -MD -m32 -gstabs -nostdinc -nostdlib 
CFLAGS += -fno-pic -static -fno-builtin -fno-strict-aliasing	\
	-fno-omit-frame-pointer -fno-stack-protector

GCC_LIB := $(shell $(CC) $(CFLAGS) -print-libgcc-file-name)

INCLUDE = -I./include
BIN_DIR = bin

# Kernel object files
KERN_OBJ = $(BIN_DIR)/init.o \
	$(BIN_DIR)/ctype.o \
	$(BIN_DIR)/stdio.o \
	$(BIN_DIR)/console.o \
	$(BIN_DIR)/kalloc.o \
	$(BIN_DIR)/kdebug.o \
	$(BIN_DIR)/vm.o

# Disk image
$(BIN_DIR)/punix.img: bootblock kernel
	dd if=/dev/zero of=$(BIN_DIR)/punix.img count=10000
	dd if=$(BIN_DIR)/bootblock of=$(BIN_DIR)/punix.img conv=notrunc
	dd if=$(BIN_DIR)/kernel of=$(BIN_DIR)/punix.img seek=1 conv=notrunc

# Build boot block
bootblock: boot/boot.S
	$(CC) $(CFLAGS) $(INCLUDE) -c -o $(BIN_DIR)/boot.o boot/boot.S
	$(LD) $(LDFLAGS) -N -e start -Ttext 0x7C00 -o $(BIN_DIR)/bootblock.o $(BIN_DIR)/boot.o
	$(OBJDUMP) -S $(BIN_DIR)/bootblock.o > $(BIN_DIR)/bootblock.asm
	$(OBJCOPY) -S -O binary -j .text $(BIN_DIR)/bootblock.o $(BIN_DIR)/bootblock

# Link the kernel
kernel: entry $(KERN_OBJ) kernel/kernel.ld
	$(LD) $(LDFLAGS) -T kernel/kernel.ld -o $(BIN_DIR)/kernel $(BIN_DIR)/entry.o $(KERN_OBJ) $(GCC_LIB)
	$(OBJDUMP) -S $(BIN_DIR)/kernel > $(BIN_DIR)/kernel.asm

entry: kernel/entry.S
	$(CC) $(CFLAGS) $(INCLUDE) -c -o $(BIN_DIR)/entry.o kernel/entry.S

# Build kernel sources
$(BIN_DIR)/%.o: kernel/%.c
	$(CC) $(CFLAGS) $(INCLUDE) -c -o $@ $<

clean: 
	rm -f $(BIN_DIR)/*

QEMUOPTS = -hda $(BIN_DIR)/punix.img -serial mon:stdio

qemu: $(BIN_DIR)/punix.img
	qemu $(QEMUOPTS)

qemu-gdb: $(BIN_DIR)/punix.img
	qemu $(QEMUOPTS) -S -s
